import { Stage } from './Stage'
import { select } from 'd3-selection'
import { timer } from 'd3-timer'
import dayjs from 'dayjs'
export class Controller {
  stage: Stage
  constructor (stage: Stage) {
    this.stage = stage
  }

  render () {
    const ctrl = select('body')
      .insert('div', ':first-child')
      .attr('id', 'anichart-ctrl')
      .attr(
        'style',
        'border-radius:10px; width:300px; position: absolute; z-index: 9;   background: #ffffff55; -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); border-width: 1px 1px 5px 1px; border-style: solid; border-color: #d3d3d3; text-align: center;',
      )
    ctrl.datum(this.stage)
    const dragger = ctrl
      .append('div')
      .attr(
        'style',
        'border-radius:10px 10px 0px 0px; padding: 10px; cursor: move; z-index: 10; background-color: #2196F3DD; color: #fff;',
      )
      .attr('id', 'anichart-ctrl-dragger')
    dragger.append('div').text('Anichart Controller')
    const timeLabel = ctrl.append('div').style('margin-top', '10px')
    const progresser = ctrl
      .append('div')
      .style('padding-left', '10px')
      .style('padding-right', '10px')
      .append('input')
      .attr('type', 'range')
      .attr('style', 'width: 100%; ')
      .attr('step', 'any')
      .attr('min', 0)
      .attr('value', 0)
      .attr('max', (d: Stage) => d.options.sec)
      .on('input', function (_, d: Stage) {
        d.sec = Number(this.value)
        void d.render()
      })
    const play = ctrl
      .append('div')
      .style('padding-bottom', '10px')
      .append('button')
      .attr(
        'style',
        'width: 90px; background-color: #2196F3DD; border: none; border-radius:10px; color: white; padding: 12px 12px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px;',
      )
      .on('click', function (_, d: Stage) {
        void d.play()
      })
    this.makeDraggable('anichart-ctrl', 'anichart-ctrl-dragger')
    timer(() => {
      timeLabel.text(
        (d: Stage) =>
          `${dayjs(d.sec * 1000).format('mm:ss')} /
          ${dayjs(d.options.sec * 1000).format('mm:ss')}`,
      )
      if (this.stage.playing) {
        const node = progresser.node()
        if (node) {
          node.value = this.stage.sec.toString()
        }
      }
      play.text((d: Stage) => (d.playing ? 'PAUSE' : 'PLAY'))
    })
  }

  makeDraggable (contentID: string, draggerID: string) {
    // Make the DIV element draggable:
    const div = document.getElementById(contentID)
    const dragger = document.getElementById(draggerID)
    if ((div != null) && (dragger != null)) dragElement(div, dragger)
    function dragElement (elmnt: HTMLElement, dragger: HTMLElement) {
      let pos1 = 0
      let pos2 = 0
      let pos3 = 0
      let pos4 = 0
      if (dragger) {
        // if present, the header is where you move the DIV from:
        dragger.onmousedown = dragMouseDown
      } else {
        // otherwise, move the DIV from anywhere inside the DIV:
        elmnt.onmousedown = dragMouseDown
      }

      function dragMouseDown (e) {
        e = e || window.event
        e.preventDefault()
        // get the mouse cursor position at startup:
        pos3 = e.clientX
        pos4 = e.clientY
        document.onmouseup = closeDragElement
        // call a function whenever the cursor moves:
        document.onmousemove = elementDrag
      }

      function elementDrag (e) {
        e = e || window.event
        e.preventDefault()
        // calculate the new cursor position:
        pos1 = pos3 - e.clientX
        pos2 = pos4 - e.clientY
        pos3 = e.clientX
        pos4 = e.clientY
        // set the element's new position:
        elmnt.style.top = `${elmnt.offsetTop - pos2}px`
        elmnt.style.left = `${elmnt.offsetLeft - pos1}px`
      }

      function closeDragElement () {
        // stop moving when mouse button is released:
        document.onmouseup = null
        document.onmousemove = null
      }
    }
  }
}
